/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.emergency.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.koron.audit.approval.AfterApprovalService;
import com.koron.audit.domain.Audit;
import com.koron.audit.management.FlowManagement;
import com.koron.common.bean.StaffBean;
import com.koron.common.dfs.FastDFSClientWrapper;
import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.common.generator.GetHardwareIdFailedException;
import com.koron.common.generator.InvalidSystemClockException;
import com.koron.common.util.DocConverterUtils;
import com.koron.emergency.domain.ContingencyPlan;
import com.koron.emergency.domain.ResponseLevel;
import com.koron.emergency.mapper.ContingencyPlanMapper;
import com.koron.emergency.mapper.DrillPlanMapper;
import com.koron.emergency.mapper.EmergencyResponseMapper;
import com.koron.emergency.mapper.ResponseLevelMapper;
import com.koron.emergency.service.api.ContingencyPlanService;
import com.koron.emergency.util.BusinessCode;
import com.koron.risk.bean.CorpBean;
import com.koron.risk.mapper.CorpManagementMapper;
import com.koron.safetytask.domain.JobsTasks;
import com.koron.safetytask.mapper.JobsTasksMapper;
import com.koron.system.domain.DictData;
import com.koron.system.mapper.DictDataMapper;
import com.koron.system.service.api.DictDataService;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.swan.bean.MessageBean;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class ContingencyPlanServiceImpl implements ContingencyPlanService, AfterApprovalService, InitializingBean {

    private final static  Logger logger = LoggerFactory.getLogger(ContingencyPlanServiceImpl.class);
    @Autowired
    private FastDFSClientWrapper clientWrapper;

    @Autowired
    private FlowManagement flowManagement;

    @Autowired
    private DocConverterUtils docConverterUtils;

    @Autowired
    private DictDataService dictDataService;

    @Override
    public MessageBean<Integer> save(ContingencyPlan contingencyPlan, List<ResponseLevel> responseLevelList, String keepFiles, String keepPDFFiles, String delFiles, String delPDFFiles, MultipartFile[] files, StaffBean user, String approverCodeListStr, String jobsTasksId) {
        MessageBean<Integer> msg = new MessageBean<>();
        List<String> keepList = new ArrayList<>();
        List<String> keepPDFList = new ArrayList<>();
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(contingencyPlan.getCorpCode())) {
                msg.setCode(BusinessCode.CONTINGENCYPLAN_EMPTY_CORP.getCode());
                msg.setDescription(BusinessCode.CONTINGENCYPLAN_EMPTY_CORP.getDescription());
                return msg;
            }
            if (StringUtils.isEmpty(approverCodeListStr) && contingencyPlan.getState() != 2) {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("审核人不能为空");
                return msg;
            }
            List<String> approverCodeList = JSONObject.parseArray(approverCodeListStr, String.class);
            if (StringUtils.isEmpty(contingencyPlan.getContingencyPlanName())) {
                msg.setCode(BusinessCode.NAME_EMPTY_CONTINGENCYPLAN.getCode());
                msg.setDescription(BusinessCode.NAME_EMPTY_CONTINGENCYPLAN.getDescription());
                return msg;
            }
            if (StringUtils.isEmpty(contingencyPlan.getVersion())) {
                msg.setCode(BusinessCode.CONTINGENCYPLAN_EMPTY_VERSION.getCode());
                msg.setDescription(BusinessCode.CONTINGENCYPLAN_EMPTY_VERSION.getDescription());
                return msg;
            }
            if (null == contingencyPlan.getContingencyPlanType()) {
                msg.setCode(BusinessCode.TYPE_EMPTY_CONTINGENCYPLAN.getCode());
                msg.setDescription(BusinessCode.TYPE_EMPTY_CONTINGENCYPLAN.getDescription());
                return msg;
            }
            if (StringUtils.isEmpty(contingencyPlan.getSubordinateCompanyName()) || StringUtils.isEmpty(contingencyPlan.getSubordinateCompanyCode())) {
                msg.setCode(BusinessCode.COMPANY_EMPTY_SUBORDINATE.getCode());
                msg.setDescription(BusinessCode.COMPANY_EMPTY_SUBORDINATE.getDescription());
                return msg;
            }
            if (null == contingencyPlan.getPublicationDate()) {
                msg.setCode(BusinessCode.CONTINGENCYPLAN_EMPTY_PUBLICATIONDATE.getCode());
                msg.setDescription(BusinessCode.CONTINGENCYPLAN_EMPTY_PUBLICATIONDATE.getDescription());
                return msg;
            }
            if (null == contingencyPlan.getExecutionDate()) {
                msg.setCode(BusinessCode.CONTINGENCYPLAN_EMPTY_EXECUTIONDATE.getCode());
                msg.setDescription(BusinessCode.CONTINGENCYPLAN_EMPTY_EXECUTIONDATE.getDescription());
                return msg;
            }
            if (StringUtils.isEmpty(contingencyPlan.getApplicableProvisions())) {
                msg.setCode(BusinessCode.CONTINGENCYPLAN_EMPTY_APPLICABLEPROVISIONS.getCode());
                msg.setDescription(BusinessCode.CONTINGENCYPLAN_EMPTY_APPLICABLEPROVISIONS.getDescription());
                return msg;
            }
            if (null == contingencyPlan.getSortOrdinal()) {
                //如果未输入值，则默认设置为1
                contingencyPlan.setSortOrdinal(1);
            } else {
                //判断排序号是否符合要求
                if (contingencyPlan.getSortOrdinal() > 100 || contingencyPlan.getSortOrdinal() < 1) {
                    msg.setCode(BusinessCode.FAILURE.getCode());
                    msg.setDescription("排序号输入错误，请输入1-100的整数");
                    return msg;
                }
            }
            //判断时间是否合理
            if (contingencyPlan.getPublicationDate().getTime() > contingencyPlan.getExecutionDate().getTime()) {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("发布日期不能大于实施日期");
                return msg;
            }
            if (null != files && files.length > 0) {
                for (MultipartFile file : files) {
                    //获得文件名
                    String fileName = file.getOriginalFilename();
//                    //获取文件后缀名
//                    String substring = fileName.substring(fileName.lastIndexOf(".") + 1);
//                    //判断是否属于excel或word文档
//                    boolean contains = Lists.newArrayList("xls", "xlsx", "XLS", "XLSX", "doc", "DOC", "docx", "DOCX").contains(substring);
//                    if (!contains) {
//                        msg.setCode(BusinessCode.FAILURE.getCode());
//                        msg.setDescription(fileName + "不是excel文件或word文件，请上传excel文件或者word文件");
//                        return msg;
//                    }
                    //文件上传
                    String url = clientWrapper.uploadFile(file);
                    keepList.add(url + "#" + fileName);
                    String pdfFilePath = docConverterUtils.converterUpdate(file);
                    if (StringUtils.isNotEmpty(pdfFilePath)) {
                        keepPDFList.add(pdfFilePath);
                    } else {
                        keepPDFList.add(null);
                    }
                }
            }
            if (StringUtils.isEmpty(contingencyPlan.getContingencyPlanCode()) || null == contingencyPlan.getContingencyPlanCode()) {
                //如果没有传入预案编号，自动生成一个
                contingencyPlan.setContingencyPlanCode(generateCode(factory, contingencyPlan.getCorpCode(), contingencyPlan.getContingencyPlanType()));
                //判断预案编号是否已存在
                Integer integer = factory.getMapper(ContingencyPlanMapper.class).queryByContingencyPlanCode(contingencyPlan.getContingencyPlanCode(), contingencyPlan.getCorpCode(), contingencyPlan.getId());
                while (integer > 0) {
                    contingencyPlan.setContingencyPlanCode(String.valueOf(Integer.parseInt(contingencyPlan.getContingencyPlanCode()) + 1));
                    integer = factory.getMapper(ContingencyPlanMapper.class).queryByContingencyPlanCode(contingencyPlan.getContingencyPlanCode(), contingencyPlan.getCorpCode(), contingencyPlan.getId());
                }
            } else {
                //传入预案编号时，判断是否已存在
                Integer integer = factory.getMapper(ContingencyPlanMapper.class).queryByContingencyPlanCode(contingencyPlan.getContingencyPlanCode(), contingencyPlan.getCorpCode(), contingencyPlan.getId());
                if (integer > 0) {
                    msg.setCode(BusinessCode.FAILURE.getCode());
                    msg.setDescription("您输入的应急预案编号已存在，请重新输入");
                    return msg;
                }
            }
            //根据预案名称和版本号判重
            if (StringUtils.isNotEmpty(contingencyPlan.getContingencyPlanName()) && StringUtils.isNotEmpty(contingencyPlan.getVersion()) && StringUtils.isNotEmpty(contingencyPlan.getId())) {
                Integer count = factory.getMapper(ContingencyPlanMapper.class).queryCountWithId(contingencyPlan.getContingencyPlanName(), contingencyPlan.getVersion(), contingencyPlan.getCorpCode(), contingencyPlan.getId());
                if (count > 0) {
                    msg.setCode(BusinessCode.FAILURE.getCode());
                    msg.setDescription("应急预案有重复，请先废弃旧预案，或者重新输出！");
                    return msg;
                }
            }
            Integer value = 0;
            //判断是否是已存在的预案，id不存在，则为新增，id存在，则为修改
            if (StringUtils.isEmpty(contingencyPlan.getId())) {
                contingencyPlan.setAddTime(contingencyPlan.getUpdateTime());
                contingencyPlan.setAddUser(contingencyPlan.getUpdateUser());
                contingencyPlan.setAddUserName(contingencyPlan.getUpdateUserName());
                contingencyPlan.setId(DefaultIdGenerator.getInstance().generateLongId());
                if (null != keepList && keepList.size() > 0) {
                    contingencyPlan.setAttachment(new Gson().toJson(keepList));
                }
                if (null != keepPDFList && keepPDFList.size() > 0) {
                    contingencyPlan.setPreviewAttachment(new Gson().toJson(keepPDFList));
                }
                value = factory.getMapper(ContingencyPlanMapper.class).insert(contingencyPlan);
                if (value > 0) {
                    if (null != responseLevelList && responseLevelList.size() > 0) {
                        for (ResponseLevel responseLevel : responseLevelList) {
                            responseLevel.setId(DefaultIdGenerator.getInstance().generateLongId());
                            responseLevel.setContingencyPlanId(contingencyPlan.getId());
                        }
                        value = factory.getMapper(ResponseLevelMapper.class).batchInsert(responseLevelList);
                        if (value > 0) {
                            if (contingencyPlan.getState() == 1) {
                                // 启动流程
                                Boolean flag = startAudit(contingencyPlan, user, approverCodeList, jobsTasksId, "新增应急预案待审核", "新增应急预案提交审核", "contingency_plan_creation");
                                if (!flag) {
                                    factory.close(false);
                                    msg.setCode(BusinessCode.FAILURE.getCode());
                                    msg.setDescription("新增应急预案流程启动失败");
                                    return msg;
                                } else {
                                    //更新任务状态
                                    if (StringUtils.isNotEmpty(jobsTasksId)) {
                                        JobsTasks jobsTasks = factory.getMapper(JobsTasksMapper.class).queryById(jobsTasksId);
                                        if (jobsTasks == null) {
                                            factory.close(false);
                                            msg.setCode(BusinessCode.NOT_CHANGE_DATA.getCode());
                                            msg.setDescription("该工作任务已失效,请刷新!");
                                            return msg;
                                        }
                                        //设置任务状态：-1废弃，0待办，1完成，2延时完成，3执行中
                                        jobsTasks.setBusinessId(contingencyPlan.getId());
                                        jobsTasks.setState(3);
                                        //设置任务流程状态  0草稿 1审批中 2审批通过
                                        jobsTasks.setFstatusflag(1);
                                        int completed = factory.getMapper(JobsTasksMapper.class).completed(jobsTasks);
                                        if (completed != 1) {
                                            factory.close(false);
                                            msg.setCode(BusinessCode.EXCEPTION.getCode());
                                            msg.setDescription("该工作任务已失效,请刷新!");
                                            return msg;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (value > 0) {
                    factory.close();
                    msg.setCode(BusinessCode.SUCCESS.getCode());
                    msg.setDescription("应急预案保存成功");
                    return msg;
                } else {
                    factory.close(false);
                    msg.setCode(BusinessCode.FAILURE.getCode());
                    msg.setDescription("保存失败");
                    return msg;
                }
            } else {
                //修改
                ContingencyPlan entity = queryOne(contingencyPlan.getId()).getData();
                if (null == entity) {
                    msg.setCode(BusinessCode.CONTINGENCYPLAN_NOT_EXIST.getCode());
                    msg.setDescription(BusinessCode.CONTINGENCYPLAN_NOT_EXIST.getDescription());
                    return msg;
                } else if (null != entity && entity.getState() != 0 && entity.getState() != 2) {
                    msg.setCode(BusinessCode.FAILURE.getCode());
                    msg.setDescription("审核中的数据不能修改");
                    return msg;
                }
                if (StringUtils.isNotEmpty(keepFiles)) {
                    String[] keepArray = keepFiles.split("[;；]");
                    keepList.addAll(Arrays.asList(keepArray));
                }
                if (null != keepList && keepList.size() > 0) {
                    contingencyPlan.setAttachment(new Gson().toJson(keepList));
                }
                if (StringUtils.isNotEmpty(keepPDFFiles)) {
                    String[] keepPDFArray = keepPDFFiles.split("[;；]");
                    keepPDFList.addAll(Arrays.asList(keepPDFArray));
                }
                if (null != keepPDFList && keepPDFList.size() > 0) {
                    contingencyPlan.setPreviewAttachment(new Gson().toJson(keepPDFList));
                }
                if (entity.getState() == 2 && contingencyPlan.getState() == 2) {
                    value = factory.getMapper(ContingencyPlanMapper.class).update(contingencyPlan);
                    if (value > 0) {
                        if (responseLevelList != null && responseLevelList.size() > 0) {
                            //先删除原有的响应等级数据，再重新添加
                            List<ResponseLevel> delList = factory.getMapper(ResponseLevelMapper.class).queryByContingencyPlanId(contingencyPlan.getId(), null, null);
                            if (null != delList && delList.size() > 0) {
                                for (ResponseLevel responseLevel : delList) {
                                    String contingencyPlanId = responseLevel.getContingencyPlanId();
                                    //根据应急预案id删除响应等级信息
                                    factory.getMapper(ResponseLevelMapper.class).delete(contingencyPlanId);
                                }
                            }
                            for (ResponseLevel responseLevel : responseLevelList) {
                                responseLevel.setId(DefaultIdGenerator.getInstance().generateLongId());
                                responseLevel.setContingencyPlanId(contingencyPlan.getId());
                            }
                            value = factory.getMapper(ResponseLevelMapper.class).batchInsert(responseLevelList);
                        }
                    }
                } else if (entity.getState() == 2 && contingencyPlan.getState() == 1) {
                    if (responseLevelList != null && responseLevelList.size() > 0) {
                        contingencyPlan.setState(1);
                        //更新主表状态
                        value = factory.getMapper(ContingencyPlanMapper.class).update(contingencyPlan);
                        if (value > 0) {
                            //先删除原有的响应等级数据，再重新添加
                            List<ResponseLevel> delList = factory.getMapper(ResponseLevelMapper.class).queryByContingencyPlanId(contingencyPlan.getId(), null, null);
                            if (null != delList && delList.size() > 0) {
                                for (ResponseLevel responseLevel : delList) {
                                    String contingencyPlanId = responseLevel.getContingencyPlanId();
                                    //根据应急预案id删除响应等级信息
                                    factory.getMapper(ResponseLevelMapper.class).delete(contingencyPlanId);
                                }
                            }
                            for (ResponseLevel responseLevel : responseLevelList) {
                                responseLevel.setId(DefaultIdGenerator.getInstance().generateLongId());
                                responseLevel.setContingencyPlanId(contingencyPlan.getId());
                            }
                            value = factory.getMapper(ResponseLevelMapper.class).batchInsert(responseLevelList);
                            if (value > 0) {
                                //启动流程
                                Boolean flag = startAudit(contingencyPlan, user, approverCodeList, null, "新增应急预案待审核", "新增应急预案提交审核", "contingency_plan_creation");
                                if (!flag) {
                                    factory.close(false);
                                    msg.setCode(BusinessCode.FAILURE.getCode());
                                    msg.setDescription("应急预案提交失败");
                                    return msg;
                                } else {
                                    factory.close();
                                    msg.setCode(BusinessCode.SUCCESS.getCode());
                                    msg.setDescription("应急预案提交成功");
                                    return msg;
                                }
                            }
                        }
                    }
                } else if (entity.getState() == 0 && contingencyPlan.getState() == 1) {
                    if (responseLevelList != null && responseLevelList.size() > 0) {
                        entity.setState(3);
                        //更新主表状态
                        value = factory.getMapper(ContingencyPlanMapper.class).update(entity);
                        if (value > 0) {
                            //将修改的应急预案数据写入副表
                            contingencyPlan.setAddTime(entity.getAddTime());
                            contingencyPlan.setAddUser(entity.getAddUser());
                            contingencyPlan.setAddUserName(entity.getAddUserName());
                            ContingencyPlan plan = factory.getMapper(ContingencyPlanMapper.class).queryOneOnAuxiliary(entity.getId());
                            if (null != plan) {
                                //副表有记录，更新
                                factory.getMapper(ContingencyPlanMapper.class).updateOnAuxiliary(contingencyPlan);
                                List<ResponseLevel> oldLevels = factory.getMapper(ResponseLevelMapper.class).queryResponseLevelOnAuxiliary(entity.getId());
                                if (null != oldLevels) {//先删除原来的记录
                                    for (ResponseLevel oldLevel : oldLevels) {
                                        factory.getMapper(ResponseLevelMapper.class).deleteOnAuxiliary(oldLevel.getContingencyPlanId());
                                    }
                                }
                                //再将修改的响应等级信息写入副表中
                                for (ResponseLevel responseLevel : responseLevelList) {
                                    responseLevel.setId(DefaultIdGenerator.getInstance().generateLongId());
                                    responseLevel.setContingencyPlanId(contingencyPlan.getId());
                                }
                                value = factory.getMapper(ResponseLevelMapper.class).batchInsertToAuxiliary(responseLevelList);
                            } else {
                                factory.getMapper(ContingencyPlanMapper.class).insertAuxiliary(contingencyPlan);
                                //将修改的响应等级信息写入副表中
                                for (ResponseLevel responseLevel : responseLevelList) {
                                    responseLevel.setId(DefaultIdGenerator.getInstance().generateLongId());
                                    responseLevel.setContingencyPlanId(contingencyPlan.getId());
                                }
                                value = factory.getMapper(ResponseLevelMapper.class).batchInsertToAuxiliary(responseLevelList);
                            }
                            if (value > 0) {
                                //启动流程
                                Boolean flag = startAudit(contingencyPlan, user, approverCodeList, null, "修改应急预案待审核", "修改应急预案提交审核", "contingency_plan_creation");

                                if (!flag) {
                                    factory.close(false);
                                    msg.setCode(BusinessCode.FAILURE.getCode());
                                    msg.setDescription("修改应急预案提交失败");
                                    return msg;
                                } else {
                                    factory.close();
                                    msg.setCode(BusinessCode.SUCCESS.getCode());
                                    msg.setDescription("修改应急预案提交成功");
                                    return msg;
                                }
                            }
                        }
                    }
                }
            }
            if (value > 0) {
                if (StringUtils.isNotEmpty(delFiles)) {
                    String[] delArray = delFiles.split("[;；]");
                    for (String delUrl : delArray) {
                        clientWrapper.deleteFile(delUrl.split("#")[0]);
                    }
                }
                if (StringUtils.isNotEmpty(delPDFFiles)) {
                    String[] delArray = delPDFFiles.split("[;；]");
                    for (String delUrl : delArray) {
                        clientWrapper.deleteFile(delUrl.split("#")[0]);
                    }
                }
            }
            msg.setData(value);
            if (value < 0) {
                if (null != keepList && keepList.size() > 0) {
                    if (StringUtils.isEmpty(keepFiles)) {
                        for (String url : keepList) {
                            clientWrapper.deleteFile(url.split("#")[0]);
                        }
                    } else {
                        List<String> keeps = Arrays.asList(keepFiles.split("[;；]"));
                        for (String url : keepList) {
                            if (!keeps.contains(url)) {
                                clientWrapper.deleteFile(url.split("#")[0]);
                            }
                        }
                    }
                }
                if (null != keepPDFList && keepPDFList.size() > 0) {
                    if (StringUtils.isEmpty(keepPDFFiles)) {
                        for (String pdfUrl : keepPDFList) {
                            //获取文件后缀名
                            String substring = pdfUrl.substring(pdfUrl.lastIndexOf(".") + 1);
                            boolean contains = Lists.newArrayList("pdf", "PDF").contains(substring);
                            if (contains) {
                                clientWrapper.deleteFile(pdfUrl.split("#")[0]);
                            }
                        }
                    } else {
                        List<String> keeps = Arrays.asList(keepPDFFiles.split("[;；]"));
                        for (String pdfUrl : keepPDFList) {
                            if (!keeps.contains(pdfUrl)) {
                                //获取文件后缀名
                                String substring = pdfUrl.substring(pdfUrl.lastIndexOf(".") + 1);
                                boolean contains = Lists.newArrayList("pdf", "PDF").contains(substring);
                                if (contains) {
                                    clientWrapper.deleteFile(pdfUrl.split("#")[0]);
                                }
                            }
                        }
                    }
                }
                factory.close(false);
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("保存失败");
            }
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            if (null != keepList && keepList.size() > 0) {
                if (StringUtils.isEmpty(keepFiles)) {
                    for (String url : keepList) {
                        clientWrapper.deleteFile(url.split("#")[0]);
                    }
                } else {
                    List<String> keeps = Arrays.asList(keepFiles.split("[;；]"));
                    for (String url : keepList) {
                        if (!keeps.contains(url)) {
                            clientWrapper.deleteFile(url.split("#")[0]);
                        }
                    }
                }
            }
            if (null != keepPDFList && keepPDFList.size() > 0) {
                for (String pdfUrl : keepPDFList) {
                    //获取文件后缀名
                    String substring = pdfUrl.substring(pdfUrl.lastIndexOf(".") + 1);
                    boolean contains = Lists.newArrayList("pdf", "PDF").contains(substring);
                    if (contains) {
                        clientWrapper.deleteFile(pdfUrl.split("#")[0]);
                    }
                }
            }
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }

    }

    /**
     * 启动流程
     *
     * @param contingencyPlan  应急预案
     * @param user             当前登陆人
     * @param approverCodeList 审批人
     * @param jobsTasksId      工作任务id
     * @param title            流程标题、名称
     * @param description      流程描述
     * @param templatekey      流程模板
     * @return
     * @throws InvalidSystemClockException
     * @throws GetHardwareIdFailedException
     */
    private Boolean startAudit(ContingencyPlan contingencyPlan, StaffBean user, List<String> approverCodeList, String jobsTasksId, String title, String description, String templatekey) throws InvalidSystemClockException, GetHardwareIdFailedException {
        Audit audit = new Audit();
        audit.setId(DefaultIdGenerator.getInstance().generateLongId());
        audit.setUpdateUser(contingencyPlan.getUpdateUserName());
        audit.setUpdateTime(contingencyPlan.getUpdateTime());
        audit.setAddUser(contingencyPlan.getUpdateUserName());
        audit.setAddTime(contingencyPlan.getUpdateTime());
        audit.setFlowType(1);
        audit.setOperation(1);
        audit.setTarget(ContingencyPlanServiceImpl.class.getName());
        audit.setFlowName(title);
        audit.setTitle(title);
        audit.setCorpCode(contingencyPlan.getCorpCode());
        audit.setInitiatorCode(user.getCode());
        audit.setDescription(description);
        audit.setState(1);
        audit.setTemplateKey(templatekey);
        // 模板组code
        audit.setSetCode("contingency_manage");
        audit.setInitiatorAccount(user.getUserid());
        audit.setBusinessIds(contingencyPlan.getId());
        //将工作任务id设置到流程中的其他关联业务id中
        if (null != jobsTasksId) {
            audit.setOtherBusinessIds(jobsTasksId);
        }
        List<String> idLists = new ArrayList<>();
        idLists.add(contingencyPlan.getId());
        audit.setBusinessIds(new Gson().toJson(idLists));
        Map<String, Object> businessMap = new HashMap<>();
        StringBuilder codes = new StringBuilder();
        for (String code : approverCodeList) {
            codes.append(code.split("_")[0]).append(",");
        }
        businessMap.put("approver", codes.toString().substring(0, codes.lastIndexOf(",")));
        return flowManagement.initFlow(user, audit, businessMap);
    }

    @Override
    public MessageBean<ContingencyPlan> queryOne(String id) {
        MessageBean<ContingencyPlan> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), "查询应急预案成功", ContingencyPlan.class);
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(id)) {
                msg.setCode(BusinessCode.NOT_CHANGE_DATA.getCode());
                msg.setDescription(BusinessCode.NOT_CHANGE_DATA.getDescription());
                return msg;
            }
            ContingencyPlan entity = factory.getMapper(ContingencyPlanMapper.class).queryOne(id);
            if (null == entity) {
                msg.setCode(BusinessCode.CONTINGENCYPLAN_NOT_EXIST.getCode());
                msg.setDescription(BusinessCode.CONTINGENCYPLAN_NOT_EXIST.getDescription());
                return msg;
            } else {
                List<ResponseLevel> responseLevels = factory.getMapper(ResponseLevelMapper.class).queryByContingencyPlanId(entity.getId(), null, null);
                entity.setResponseLevelList(responseLevels);
                getName(entity);
                msg.setData(entity);
                return msg;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    private void getName(ContingencyPlan bean) {
        if (null != bean) {
            Map<String, DictData> cacheMap = dictDataService.getCacheMap();
            if (StringUtils.isNotBlank(bean.getContingencyPlanType())) {
                DictData element = cacheMap.get(bean.getContingencyPlanType());
                bean.setContingencyPlanTypeName(element != null ? element.getDictLabel() : "");
            }
        }
    }

    @Override
    public MessageBean<Integer> delete(String id, StaffBean user, String approverCodeListStr) {
        MessageBean<Integer> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), "删除成功", Integer.class);
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(id)) {
                msg.setCode(BusinessCode.NOT_CHANGE_DATA.getCode());
                msg.setDescription(BusinessCode.NOT_CHANGE_DATA.getDescription());
                return msg;
            }
            List<String> approverCodeList = JSONObject.parseArray(approverCodeListStr, String.class);
            ContingencyPlan entity = queryOne(id).getData();
            if (StringUtils.isEmpty(approverCodeListStr) && entity.getState() != 2) {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("审核人不能为空");
                return msg;
            }
            // 查找应急预案是否在应急响应中引用
            Integer count = factory.getMapper(EmergencyResponseMapper.class).queryByPlanId(id);
            // 查找应急预案是否在应急演练中引用
            Integer count1 = factory.getMapper(DrillPlanMapper.class).queryByPlanId(id);
            if (count > 0 || count1 > 0) {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("该应急预案已经被引用，无法删除！");
                return msg;
            }
            if (null == entity) {
                msg.setData(BusinessCode.CONTINGENCYPLAN_NOT_EXIST.getCode());
                msg.setDescription(BusinessCode.CONTINGENCYPLAN_NOT_EXIST.getDescription());
                return msg;
            } else if (entity.getState() != 0 && entity.getState() != 2) {
                msg.setData(BusinessCode.FAILURE.getCode());
                msg.setDescription("审批中的数据不能删除");
                return msg;
            } else if (entity.getState() == 2) {
                //草稿状态直接删除
                Integer delete = factory.getMapper(ContingencyPlanMapper.class).delete(entity.getId());
                if (delete > 0) {
                    msg.setCode(BusinessCode.SUCCESS.getCode());
                    msg.setDescription("删除成功");
                    return msg;
                }
            } else if (entity.getState() == 0) {
                entity.setState(4);
                factory.getMapper(ContingencyPlanMapper.class).update(entity);
                //启动流程
                Boolean flag = startAudit(entity, user, approverCodeList, null, "删除应急预案待审核", "删除应急预案提交审核", "contingency_plan_deletion");
                if (!flag) {
                    factory.close(false);
                    msg.setCode(BusinessCode.FAILURE.getCode());
                    msg.setDescription("删除应急预案提交失败");
                    return msg;
                } else {
                    factory.close();
                    msg.setCode(BusinessCode.SUCCESS.getCode());
                    msg.setDescription("删除应急预案提交成功");
                }
            }
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    @Override
    public MessageBean<DataBean<ContingencyPlan>> list(String corpCode, String contingencyPlanName, String contingencyPlanType, Integer start, Integer rows) {
        MessageBean<DataBean<ContingencyPlan>> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            rows = (rows == null || rows <= 0) ? 1 : rows;
            List<ContingencyPlan> list = factory.getMapper(ContingencyPlanMapper.class).queryByCondition(corpCode, contingencyPlanName, contingencyPlanType, start, rows);
            for (ContingencyPlan contingencyPlan : list) {
                List<ResponseLevel> responseLevels = factory.getMapper(ResponseLevelMapper.class).queryByContingencyPlanId(contingencyPlan.getId(), null, null);
                contingencyPlan.setResponseLevelList(responseLevels);
            }
            Integer totalNumber = factory.getMapper(ContingencyPlanMapper.class).countByCondition(corpCode, contingencyPlanName, contingencyPlanType);
            Integer totalPage = (totalNumber > rows) ? (totalNumber % rows == 0 ? totalNumber / rows : totalNumber / rows + 1) : 1;
            DataBean<ContingencyPlan> dataBean = new DataBean<>();
            list.forEach(contingencyPlan -> getName(contingencyPlan));
            dataBean.setList(list);
            dataBean.setTotalPage(totalPage);
            dataBean.setTotalNumber(totalNumber);
            dataBean.setPageSize(rows);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("查询应急预案列表成功");
            msg.setData(dataBean);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    @Override
    public MessageBean<List<ContingencyPlan>> queryAll(String corpCode, String contingencyPlanName) {
        MessageBean<List<ContingencyPlan>> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            List<ContingencyPlan> list = factory.getMapper(ContingencyPlanMapper.class).queryContingencyPlan(corpCode, contingencyPlanName);
            for (ContingencyPlan contingencyPlan : list) {
                List<ResponseLevel> responseLevels = factory.getMapper(ResponseLevelMapper.class).queryByContingencyPlanId(contingencyPlan.getId(), null, null);
                contingencyPlan.setResponseLevelList(responseLevels);
            }
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("查询应急预案列表成功");
            msg.setData(list);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    @Override
    public String generateCode(SessionFactory factory, String corpCode, String ContingencyPlanType) {
        StringBuilder code = new StringBuilder();
        CorpManagementMapper corpMapper = factory.getMapper(CorpManagementMapper.class);
        CorpBean corpBean = corpMapper.get(corpCode);
        if (corpBean == null) {
            code.append("#####");
        } else {
            code.append(corpBean.getShortCode());
        }
        if (StringUtils.isEmpty(code)) {
            code.append("#####");
        }
        DictData materialTypeData = factory.getMapper(DictDataMapper.class).queryOne(ContingencyPlanType);
        if (materialTypeData != null) {
            code.append(materialTypeData.getDictValue());
        }
        Integer count = factory.getMapper(ContingencyPlanMapper.class).countByCondition(corpCode, null, ContingencyPlanType);
        NumberFormat nf = NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        nf.setMaximumIntegerDigits(3); // 设置最大整数位数
        nf.setMinimumIntegerDigits(3); // 设置最小整数位数
        code.append(nf.format(count));
        return code.toString();
    }

    @Override
    public MessageBean<List<ResponseLevel>> queryByContingencyPlanId(String contingencyPlanId) {
        MessageBean<List<ResponseLevel>> responseLevelList = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(contingencyPlanId)) {
                responseLevelList.setCode(BusinessCode.NOT_CHANGE_DATA.getCode());
                responseLevelList.setDescription(BusinessCode.NOT_CHANGE_DATA.getDescription());
                return responseLevelList;
            }
            List<ResponseLevel> responseLevels = factory.getMapper(ResponseLevelMapper.class).queryResponseLevelByPlanId(contingencyPlanId);
            if (responseLevels.size() <= 0 || null == responseLevels) {
                responseLevelList.setCode(BusinessCode.FAILURE.getCode());
                responseLevelList.setDescription("响应等级信息不存在");
                return responseLevelList;
            }
            responseLevelList.setData(responseLevels);
            responseLevelList.setCode(BusinessCode.SUCCESS.getCode());
            responseLevelList.setDescription("查询响应等级信息列表成功");
            return responseLevelList;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            responseLevelList.setCode(BusinessCode.EXCEPTION.getCode());
            responseLevelList.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return responseLevelList;
    }

    @Override
    public MessageBean<?> getProcessData(String ids) {
        MessageBean<List<ContingencyPlan>> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory();) {
            if (StringUtils.isNotBlank(ids)) {
                List<String> idList = JSONObject.parseArray(ids, String.class);
                if (idList != null && !idList.isEmpty()) {
                    for (String id : idList) {
                        ContingencyPlanMapper mapper = factory.getMapper(ContingencyPlanMapper.class);
                        ContingencyPlan contingencyPlan = mapper.queryOne(id);
                        List<ContingencyPlan> contingencyPlanList = new ArrayList<>();
                        if (contingencyPlan.getState() == 3) {
                            ContingencyPlan contingencyPlan1 = mapper.queryOneOnAuxiliary(id);
                            List<ResponseLevel> responseLevelOnAuxiliary = factory.getMapper(ResponseLevelMapper.class).queryResponseLevelOnAuxiliary(contingencyPlan1.getId());
                            contingencyPlan1.setResponseLevelList(responseLevelOnAuxiliary);
                            contingencyPlanList.add(contingencyPlan1);
                            msg.setData(contingencyPlanList);
                        } else {
                            List<ResponseLevel> responseLevels = factory.getMapper(ResponseLevelMapper.class).queryByContingencyPlanId(contingencyPlan.getId(), null, null);
                            contingencyPlan.setResponseLevelList(responseLevels);
                            contingencyPlanList.add(contingencyPlan);
                            msg.setData(contingencyPlanList);
                        }
                    }
                }
            } else {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("id不能为空");
            }
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            return msg;
        }
    }

    @Override
    public MessageBean<Map> getResponseLevel(String contingencyPlanId) {
        MessageBean<Map> responseLevelList = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(contingencyPlanId)) {
                responseLevelList.setCode(BusinessCode.NOT_CHANGE_DATA.getCode());
                responseLevelList.setDescription(BusinessCode.NOT_CHANGE_DATA.getDescription());
                return responseLevelList;
            }
            List<ResponseLevel> responseLevels = factory.getMapper(ResponseLevelMapper.class).queryResponseLevelByPlanId(contingencyPlanId);
            if (responseLevels.size() <= 0 || null == responseLevels) {
                responseLevelList.setCode(BusinessCode.FAILURE.getCode());
                responseLevelList.setDescription("响应等级信息不存在");
                return responseLevelList;
            }
            // 对根据响应等级的进行归类，将同一等级的信息放在一起
            Map<String, List<ResponseLevel>> collect = responseLevels.stream().collect(Collectors.groupingBy(responseLevel -> responseLevel.getLevel()));
            responseLevelList.setData(collect);
            responseLevelList.setCode(BusinessCode.SUCCESS.getCode());
            responseLevelList.setDescription("查询响应等级信息列表成功");
            return responseLevelList;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            responseLevelList.setCode(BusinessCode.EXCEPTION.getCode());
            responseLevelList.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return responseLevelList;
    }

    @Override
    public List<ContingencyPlan> exportList(StaffBean user, String corpCode, String contingencyPlanName, String contingencyPlanType) {
        try (SessionFactory factory = new SessionFactory()) {
            List<ContingencyPlan> list = factory.getMapper(ContingencyPlanMapper.class).queryByCondition(corpCode, contingencyPlanName, contingencyPlanType, null, null);
            if (null != list && list.size() > 0) {
                Map<String, DictData> cacheMap = dictDataService.getCacheMap();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                list.forEach(bean -> {
                    if (null != bean.getPublicationDate()) {
                        bean.setPublicationDateStr(sdf.format(bean.getPublicationDate()));
                    }
                    if (null != bean.getExecutionDate()) {
                        bean.setExecutionDateStr(sdf.format(bean.getExecutionDate()));
                    }
                    if (null != bean.getFilingDate()) {
                        bean.setFilingDateStr(sdf.format(bean.getFilingDate()));
                    }
                    if (StringUtils.isNotBlank(bean.getContingencyPlanType())) {
                        DictData element = cacheMap.get(bean.getContingencyPlanType());
                        bean.setContingencyPlanTypeName(element != null ? element.getDictLabel() : "");
                    }
                });
            }
            return list;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return null;
        }
    }

    @Override
    public void editApproval(Audit audit) {
        SessionFactory factory = new SessionFactory();
        try {
            List<String> idList = JSONObject.parseArray(audit.getBusinessIds(), String.class);
            String jobsTasksId = audit.getOtherBusinessIds();//获取工作任务id
            if (idList != null && !idList.isEmpty()) {
                String planId = idList.get(0);
                if (StringUtils.isNotEmpty(planId)) {
                    ContingencyPlan contingencyPlan = factory.getMapper(ContingencyPlanMapper.class).queryOne(planId);
                    if (contingencyPlan != null && contingencyPlan.getState() == 1) {
                        //审核通过后，将状态设为0
                        contingencyPlan.setState(0);
                        factory.getMapper(ContingencyPlanMapper.class).update(contingencyPlan);
                        if (StringUtils.isNotEmpty(jobsTasksId) || null != jobsTasksId) {
                            //更新任务状态
                            JobsTasks jobsTasks = factory.getMapper(JobsTasksMapper.class).queryById(jobsTasksId);
                            Date endTime = jobsTasks.getEndTime();//任务结束日期
                            jobsTasks.setCompletedTime(contingencyPlan.getUpdateTime());
                            Date completedTime = jobsTasks.getCompletedTime();//任务完成时间
                            //设置任务状态：-1废弃，0待办，1完成，2延时完成，3执行中
                            if (completedTime.before(endTime)) {
                                jobsTasks.setState(1);
                            } else {
                                jobsTasks.setState(2);
                            }
                            //设置流程状态  0草稿 1审批中 2审批通过
                            jobsTasks.setFstatusflag(2);
                            factory.getMapper(JobsTasksMapper.class).completed(jobsTasks);
                        }
                    } else if (null != contingencyPlan && contingencyPlan.getState() == 3) {
                        //修改审核通过，将副表数据更新到主表
                        ContingencyPlan contingencyPlan1 = factory.getMapper(ContingencyPlanMapper.class).queryOneOnAuxiliary(planId);
                        contingencyPlan1.setState(0);
                        factory.getMapper(ContingencyPlanMapper.class).update(contingencyPlan1);
                        //获取修改后的响应等级信息
                        List<ResponseLevel> responseLevels = factory.getMapper(ResponseLevelMapper.class).queryResponseLevelOnAuxiliary(planId);
                        //获取修改前的响应等级信息
                        List<ResponseLevel> oldResponseLevels = factory.getMapper(ResponseLevelMapper.class).queryByContingencyPlanId(planId, null, null);
                        //先删在增
                        for (ResponseLevel responseLevel : oldResponseLevels) {
                            factory.getMapper(ResponseLevelMapper.class).delete(responseLevel.getContingencyPlanId());
                        }
                        factory.getMapper(ResponseLevelMapper.class).batchInsert(responseLevels);
                    }
                }
            }
            factory.close();
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            if (null != factory)
                factory.close(false);
        }
    }

    @Override
    public void discardApproval(Audit audit) {
        SessionFactory factory = new SessionFactory();
        try {
            List<String> idList = JSONObject.parseArray(audit.getBusinessIds(), String.class);
            if (idList != null && !idList.isEmpty()) {
                String planId = idList.get(0);
                if (StringUtils.isNotEmpty(planId)) {
                    ContingencyPlan contingencyPlan = factory.getMapper(ContingencyPlanMapper.class).queryOne(planId);
                    if (contingencyPlan != null) {
                        //删除审核通过后，设置状态,0.审核通过，1.审核中,2.草稿，3修改审核中4删除审批中，5.已废弃
                        contingencyPlan.setState(5);
                        factory.getMapper(ContingencyPlanMapper.class).update(contingencyPlan);
                    }
                }
            }
            factory.close();
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            if (null != factory)
                factory.close(false);
        }
    }

    @Override
    public void processDiscard(Audit audit) {
        SessionFactory factory = new SessionFactory();
        try {
            List<String> idList = JSONObject.parseArray(audit.getBusinessIds(), String.class);
            String jobsTasksId = audit.getOtherBusinessIds();//获取工作任务id
            if (idList != null && !idList.isEmpty()) {
                String planId = idList.get(0);
                if (StringUtils.isNotEmpty(planId)) {
                    ContingencyPlan contingencyPlan = factory.getMapper(ContingencyPlanMapper.class).queryOne(planId);
                    //新增数据审核不通过
                    if (contingencyPlan != null && contingencyPlan.getState() == 1) {
                        //审核不通过，将状态设为2。草稿状态
                        contingencyPlan.setState(2);
                        factory.getMapper(ContingencyPlanMapper.class).update(contingencyPlan);
                        if (StringUtils.isNotEmpty(jobsTasksId) || null != jobsTasksId) {
                            //更新任务状态
                            JobsTasks jobsTasks = factory.getMapper(JobsTasksMapper.class).queryById(jobsTasksId);
                            //设置任务状态：-1废弃，0待办，1完成，2延时完成，3执行中
                            jobsTasks.setState(0);
                            //设置流程状态  0草稿 1审批中 2审批通过
                            jobsTasks.setFstatusflag(0);
                            factory.getMapper(JobsTasksMapper.class).completed(jobsTasks);
                        }
                    } else if (contingencyPlan != null && contingencyPlan.getState() == 3) {
                        //修改审核不通过，将主表数据恢复
                        contingencyPlan.setState(0);
                        factory.getMapper(ContingencyPlanMapper.class).update(contingencyPlan);
                    } else if (contingencyPlan != null && contingencyPlan.getState() == 4) {
                        //删除审核不通过，将数据状态回滚
                        contingencyPlan.setState(0);
                        factory.getMapper(ContingencyPlanMapper.class).update(contingencyPlan);
                    }
                }
            }
            factory.close();
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            if (null != factory)
                factory.close(false);
        }

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Map map = flowManagement.getHandlers();
        map.put(ContingencyPlanServiceImpl.class.getName(), this);
    }

    @Override
    public void reject(Audit audit, List<String> userIdList) {
        // TODO 流程驳回操作
    }

    @Override
    public void passApproval(Integer operation, Audit audit) {
        // TODO 流程提交成功操作
    }
}